package cn.lqz.bucttrain.service.impl;

import cn.lqz.bucttrain.enums.ResponseCodeEnum;
import cn.lqz.bucttrain.enums.StationStatusEnum;
import cn.lqz.bucttrain.exceptions.BaseException;
import cn.lqz.bucttrain.mapper.RouteMapper;
import cn.lqz.bucttrain.mapper.StationMapper;
import cn.lqz.bucttrain.pojo.dto.StationPageQueryDTO;
import cn.lqz.bucttrain.pojo.entity.Route;
import cn.lqz.bucttrain.pojo.entity.Station;
import cn.lqz.bucttrain.pojo.vo.PageResultVO;
import cn.lqz.bucttrain.redis.RedisService;
import cn.lqz.bucttrain.service.StationService;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import jakarta.annotation.Resource;
import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.stereotype.Service;

import java.io.InputStream;
import java.time.LocalDateTime;
import java.util.List;

@Service
@Slf4j
public class StationServiceImpl implements StationService {
    @Resource
    private StationMapper stationMapper;
    @Resource
    private RouteMapper routeMapper;
    @Resource
    private RedisService redisService;

    /**
     * 加载或查询站点列表
     * @param stationPageQueryDTO
     * @return
     */
    @Override
    public PageResultVO loadStationList(StationPageQueryDTO stationPageQueryDTO) {
        log.info("加载或查询站点列表：{}",stationPageQueryDTO);
        PageHelper.startPage(stationPageQueryDTO.getPageNo(),stationPageQueryDTO.getPageSize());
        Page<Station> page = stationMapper.findBatch(stationPageQueryDTO);
        return new PageResultVO(stationPageQueryDTO.getPageNo(),stationPageQueryDTO.getPageSize(),page.getTotal(),page.getResult());
    }

    /**
     * 添加或修改站点
     * @param station
     */
    @Override
    public void addOrUpdateStation(Station station) {
        log.info("添加或修改站点：{}",station);
        if (null==station.getStationId()){ // 添加
            // 查看是否有同名站点
            Station existStation = stationMapper.findByCityAndStationName(station.getCity(), station.getStationName());
            if (null!=existStation){
                throw new BaseException(ResponseCodeEnum.CODE_400.getCode(),"站点已存在");
            }
            stationMapper.insert(station);
        }else{ // 修改
            // 查看是否有同名站点
            Station existStation = stationMapper.findByCityAndStationName(station.getCity(), station.getStationName());
            if (null!=existStation && !existStation.getStationId().equals(station.getStationId())){
                throw new BaseException(ResponseCodeEnum.CODE_400.getCode(),"站点已存在");
            }
            Station originStation = stationMapper.findByStationId(station.getStationId());
            if(null==originStation){
                throw new BaseException(ResponseCodeEnum.CODE_600);
            }
            // 禁用或维修站点：必须要等所有列车都通过
            if (!originStation.getStatus().equals(station.getStatus()) && !ArrayUtils.contains(new int[]{StationStatusEnum.ENABLE.getStatus(),StationStatusEnum.STOP.getStatus()},station.getStatus())){
                List<Route> existRouteList = routeMapper.findExistByStationIdAndTime(station.getStationId(), LocalDateTime.now());
                if (!existRouteList.isEmpty()){
                    // 站点处于挂停状态：允许已经出发的列车经停，但不再接收新的线路选择该站点
                    throw new BaseException(ResponseCodeEnum.CODE_400.getCode(),"站点正在被路线使用，请先挂停");
                }
            }
            stationMapper.update(station);
        }
        redisService.removeStationCityList();
        redisService.removeStationNameList();
    }

    /**
     * 删除站点
     * @param stationId
     */
    @Override
    public void deleteStation(Long stationId) {
        log.info("删除站点");
        // 站点必须先禁用才能删除
        Station station = stationMapper.findByStationId(stationId);
        if (null==station){
            throw new BaseException(ResponseCodeEnum.CODE_600);
        }
        if (StationStatusEnum.DISABLE.getStatus().equals(station.getStatus())){
            throw new BaseException(ResponseCodeEnum.CODE_400.getCode(),"站点必须先处于禁用状态");
        }
        stationMapper.deleteStation(stationId);
        redisService.removeStationCityList();
        redisService.removeStationNameList();
    }

    /**
     * 获取站点城市列表
     * @return
     */
    @Override
    public List<String> loadStationCityList() {
        log.info("加载站点城市列表");
        List<String> list = redisService.loadStationCityList();
        if (list.isEmpty()){
            list = stationMapper.findBatchStationCity();
            redisService.saveStationCityList(list);
        }
        return list;
    }

    /**
     * 获取站点名称列表
     * @return
     */
    @Override
    public List<String> loadStationNameList() {
        List<String> list = redisService.loadStationNameList();
        if (list.isEmpty()){
            list = stationMapper.findBatchStationName();
            redisService.saveStationNameList(list);
        }
        return list;
    }

    /**
     * 导出站点excel表
     * @param stationList
     * @param response
     */
    @Override
    public void exportStationExcel(List<Station> stationList, HttpServletResponse response) {
        log.info("站点：导出excel表");
        InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("template/站点报表.xlsx");
        try{
            XSSFWorkbook excel = new XSSFWorkbook(inputStream);
            XSSFSheet sheet = excel.getSheet("Sheet1");
            for(int i=1;i<=stationList.size();i++){
                XSSFRow xssfRow = sheet.createRow(i);
                for(int j=0;j<5;j++){
                    xssfRow.createCell(j);
                }
            }
            for(int i=0;i<stationList.size();i++){
                Station station = stationList.get(i);
                XSSFRow row = sheet.getRow(i + 1);
                row.getCell(0).setCellValue(station.getStationId());
                row.getCell(1).setCellValue(station.getProvince());
                row.getCell(2).setCellValue(station.getCity());
                row.getCell(3).setCellValue(station.getStationName());
                row.getCell(4).setCellValue(StationStatusEnum.getByStatus(station.getStatus()).getDescription());
            }
            ServletOutputStream outputStream = response.getOutputStream();
            excel.write(outputStream);
            excel.close();
            inputStream.close();
        }catch (Exception e){
            log.error("订单导出excel表异常",e);
            throw new BaseException(ResponseCodeEnum.CODE_500);

        }
    }
}
